#ifndef DFSTOOLS_DFSRSA_H_INCLUDED
#define DFSTOOLS_DFSRSA_H_INCLUDED

/* Определения функций для длинной арифметики и криптографии RSA, T8.505-T11.316; $DVS:time$ */

#ifdef __DuS__
#define DFSRSA_EXT extern "dfstools/dfsrsa.o"
#else
#define DFSRSA_EXT extern
#endif

#include <stdint.h>

#ifdef __DuS__
typedef uint16_t	dfsrsa_t;
typedef uint32_t	dfsrsa_long_t;
typedef int32_t		dfsrsa_slong_t;
#else
typedef uint32_t	dfsrsa_t;
typedef uint64_t	dfsrsa_long_t;
typedef int64_t		dfsrsa_slong_t;
#endif

// generates public and private keys of the lengh `keylen` of numbers dfsrsa_t
// `keylen` should be a multiple of 4
// the pubkey array should be prefilled with random numbers
// the algorithm does not use any other random information
// returns -1 in case of error
DFSRSA_EXT int dfsrsa_keygen(dfsrsa_t *privkey, dfsrsa_t *pubkey, int keylen);

// encodes/decodes the message using corresponding public/private key
// `datalen` and `keylen` are measured in dfsrsa_t numbers
// key `key` should be generated by function `dfsrsa_keygen`
// `datalen` should be a multiple of half of the `keylen`
// the highest bit should be 0 in each part of message (length `keylen`/2 of dfsrsa_t)
// the result message is placed in the same array as the original
// returns -1 in case of error
DFSRSA_EXT int dfsrsa_crypt(dfsrsa_t *data, int datalen, dfsrsa_t *key, int keylen);

// compares two long numbers and return -1, 0, 1
DFSRSA_EXT int dfsrsa_cmp(dfsrsa_t *left, dfsrsa_t *right, int len);

// adds two long numbers, carry is returned (0 or 1)
DFSRSA_EXT int dfsrsa_add(dfsrsa_t *sum, dfsrsa_t *add1, dfsrsa_t *add2, int len);

DFSRSA_EXT int dfsrsa_divmod(dfsrsa_t *mod, int mlen, dfsrsa_t *div, int len, dfsrsa_t *quotient);

#undef DFSRSA_EXT

#endif
